package com.sh.data.engine.application.service.management;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.sh.data.engine.application.model.dto.base.PagerResponse;
import com.sh.data.engine.application.model.dto.management.UserDTO;
import com.sh.data.engine.application.model.dto.workspace.BaseProjectDTO;
import com.sh.data.engine.application.model.dto.workspace.ProjectDTO;
import com.sh.data.engine.application.model.dto.workspace.ProjectStatisticDTO;
import com.sh.data.engine.application.model.dto.workspace.StorageDTO;
import com.sh.data.engine.application.model.mapper.management.UserDTOMapper;
import com.sh.data.engine.application.model.mapper.management.UserDTOPageMapper;
import com.sh.data.engine.application.model.mapper.workspace.*;
import com.sh.data.engine.application.model.request.management.SaveProjectRequest;
import com.sh.data.engine.application.model.request.management.StorageSaveRequest;
import com.sh.data.engine.application.model.request.management.UserProjectSaveRequest;
import com.sh.data.engine.domain.authority.model.param.UserProjectSaveParam;
import com.sh.data.engine.domain.authority.service.UserProjectService;
import com.sh.data.engine.domain.base.model.PageResult;
import com.sh.data.engine.domain.feign.FeignUserPage;
import com.sh.data.engine.domain.management.model.param.BaseQueryParam;
import com.sh.data.engine.domain.workspace.manager.model.domain.UserDomain;
import com.sh.data.engine.domain.workspace.manager.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
@Service
public class ProjectUserApplicationService {

    @Autowired
    private UserProjectService userProjectService;

    @Autowired
    private ProjectDTOMapper projectDTOMapper;

    @Autowired
    private ProjectDTOPageMapper projectDTOPageMapper;

    @Autowired
    private ProjectStatisticPageMapper projectStatisticPageMapper;

    @Autowired
    private ProjectSaveParamMapper projectSaveParamMapper;

    @Autowired
    private StorageSaveParamMapper storageSaveParamMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private FeignUserPage feignUserPage;

    @Autowired
    private StorageDTOMapper storageDTOMapper;

    @Autowired
    private UserDTOMapper userDTOMapper;

    @Autowired
    private UserDTOPageMapper userDTOPageMapper;

    @Autowired
    private ProjectStatisticDTOMapper projectStatisticDTOMapper;

    public String deleteProject(Long projectId) {
        return userProjectService.deleteProject(projectId);
    }

    public String addProject(UserProjectSaveRequest param) {
        SaveProjectRequest saveProjectRequest = param.getProject();
        StorageSaveRequest storageSaveRequest = param.getStorage();
        UserProjectSaveParam userProjectSaveParam = new UserProjectSaveParam();
        userProjectSaveParam.setProject(projectSaveParamMapper.map(saveProjectRequest));
        userProjectSaveParam.setStorage(storageSaveParamMapper.map(storageSaveRequest));
        return userProjectService.addProject(userProjectSaveParam);
    }

    public PagerResponse<BaseProjectDTO> getProjectList(Integer pageNum, Integer pageSize) {
        var param = BaseQueryParam.builder()
            .pageNum(pageNum)
            .pageSize(pageSize)
            .build();
        var projectPageList = userProjectService.getProjectList(param);
        return projectDTOPageMapper.toPageResponse(projectPageList);
    }

    public ProjectDTO getProject(Long projectId) {
        var projectDomain = userProjectService.getProject(projectId);
        return projectDTOMapper.map(projectDomain);
    }

    public PagerResponse<ProjectStatisticDTO> getEnrichedProjectList(Integer pageNum, Integer pageSize) {
        var param = BaseQueryParam.builder()
            .pageNum(pageNum)
            .pageSize(pageSize)
            .build();
        var projectPageList = userProjectService.getEnrichedProjectList(param);
        return projectStatisticPageMapper.toPageResponse(projectPageList);
    }

    public StorageDTO getStorageInfo(Long projectId) {
        var dsPageList = userProjectService.getStorageInfo(projectId);
        return storageDTOMapper.domainToDto(dsPageList);
    }

    public List<ProjectStatisticDTO> getProjectPrivilege() {
        return userProjectService.getProjectPrivilege().stream().map(projectStatisticDTOMapper::map).toList();
    }

    public int addProjectUser(int roleId, String userName) {
        return userProjectService.addProjectUser(roleId, userName);
    }

    public int deleteProjectUser(String userName) {
        return userProjectService.deleteProjectUser(userName);
    }


    public PagerResponse<UserDTO> getProjectUser(Integer pageNum, Integer pageSize) {
        PageResult<UserDomain> projectUser = userProjectService.getProjectUser(pageNum, pageSize);
        return userDTOPageMapper.toPageResponse(projectUser);
    }

    public int updateProjectUser(String userName, int roleId) {
        return userProjectService.updateProjectUser(userName, roleId);
    }

    public PagerResponse<UserDTO> getUserPageList(Integer pageNum, Integer pageSize) {
        return userDTOPageMapper.toPageResponse(userService.getUserPageList(pageNum, pageSize));
    }

    /**
     * 提取json中的账号名
     */
    public List<String> getUserNamePageList() {
        JSONObject map = feignUserPage.getMap(1, 99999, null);
        List<Object> resources = (List<Object>) map.get("resources");
        List<String> userNames = new ArrayList<>();
        for (int i = 0; i < resources.size(); i++) {
            // 将list中的数据转成json字符串
            String jsonObject = JSON.toJSONString(resources.get(i));
            //将json转成需要的对象
            UserDTO user = JSONObject.parseObject(jsonObject, UserDTO.class);
            userNames.add(user.getUserName());
        }
        userNames.removeAll(userProjectService.getProjectUser(1, 99999).getResult().stream().map(UserDomain::getUserName).toList());
        Collections.sort(userNames);
        return userNames;
    }

    public UserDTO getUser(String userId) {
        return userDTOMapper.domainToDTO(userService.getUserDetailByIdWithoutRole(userId));
    }

}
